﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Q7.BevTree
{
    public class BevNodeParallel : BevNode
    {
        public const int CON_OR = 0;
        public const int CON_AND = 1;

        private int _finishCondition = CON_OR;
        private int[] _childrenStatus = new int[MAX_CHILDREN] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };

        public BevNodeParallel(string debugName)
            : base(debugName)
        {
            ResetChildrenStatus();
        }

        public BevNodeParallel SetFinishCondition(int condition)
        {
            _finishCondition = condition;
            return this;
        }


        protected override bool DoEvaluate(BevNodeInputParam input)
        {
            var len = Children.Count;
            for (int i = 0; i < len; i++)
            {
                if (_childrenStatus[i] == BRS_EXECUTING)
                {
                    if (!Children[i].Evaluate(input))
                    {
                        return false;
                    }
                }
            }

            return true;
        }

        protected override int DoTick(BevNodeInputParam input, BevNodeOutputParam output)
        {
            int i;
            var len = Children.Count;

            if (_finishCondition == CON_OR)
            {
                for (i = 0; i < len; i++)
                {
                    if (_childrenStatus[i] == BRS_EXECUTING)
                        _childrenStatus[i] = Children[i].Tick(input, output);

                    if (_childrenStatus[i] != BRS_EXECUTING)
                    {

                        ResetChildrenStatus();
                        return BRS_FINISH;
                    }

                }
            }
            else if (_finishCondition == CON_AND)
            {
                var finishedCount = 0;

                for (i = 0; i < len; i++)
                {
                    if (_childrenStatus[i] == BRS_EXECUTING)
                        _childrenStatus[i] = Children[i].Tick(input, output);

                    if (_childrenStatus[i] != BRS_EXECUTING)
                        ++finishedCount;
                }

                if (finishedCount == len)
                {

                    ResetChildrenStatus();
                    return BRS_FINISH;
                }
            }
            else
            {
                throw new Exception("Unknown finish condition :" + _finishCondition);
            }

            return BRS_EXECUTING;
        }

        protected override void DoTransition(BevNodeInputParam input)
        {

            ResetChildrenStatus();

            var len = Children.Count;
            for (var i = 0; i < len; i++)
                Children[i].Transition(input);
        }

        private void ResetChildrenStatus()
        {
            for (var i = 0; i < MAX_CHILDREN; i++)
                _childrenStatus[i] = BRS_EXECUTING;
        }
    }
}
